package com.ruoyi.web.controller.jjm;

import java.awt.*;
import java.awt.Color;
import java.awt.Font;
import java.awt.image.BufferedImage;
import java.io.*;
import java.lang.reflect.InvocationTargetException;
import java.net.URLEncoder;
import java.sql.Time;
import java.text.DecimalFormat;
import java.util.*;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import com.alibaba.druid.util.StringUtils;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import com.ruoyi.common.config.Global;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.IDCardUtil;
import com.ruoyi.common.utils.file.FileUtils;
import com.ruoyi.framework.util.ShiroUtils;
import com.ruoyi.framework.web.service.DictService;
import com.ruoyi.jjm.domain.*;
import com.ruoyi.jjm.service.*;
import com.ruoyi.jjm.domain.*;
import com.ruoyi.jjm.service.*;
import com.ruoyi.jjm.utils.CustomHandler;
import com.ruoyi.jjm.utils.EasyExcelUtil;
import com.ruoyi.jjm.vo.VillageInfo;
import com.ruoyi.system.domain.SysDept;
import com.ruoyi.system.domain.SysUser;
import com.ruoyi.system.service.ISysDeptService;
import org.apache.commons.collections.CollectionUtils;
import org.apache.poi.hssf.usermodel.HSSFDateUtil;
import org.apache.poi.ss.usermodel.*;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.core.page.TableDataInfo;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;

import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.websocket.server.PathParam;

/**
 * 村民信息Controller
 *
 * @author tsr
 * @date 2020-07-15
 */
@Controller
@RequestMapping("/jjm/clientUser")
public class ClientUserController extends BaseController
{
    private String prefix = "jjm/clientUser";

    @Value("${qrcode.url}")
    private String qrCodeUrl;

    @Autowired
    private ISysDeptService deptService;

    @Autowired
    private IClientUserService clientUserService;

    @Autowired
    private IGridMemeberService gridMemeberService;

    @Autowired
    private IBaolianrenService baolianrenService;

    @Autowired
    private IClientUserOrderService clientUserOrderService;

    @Autowired
    private IVillageService villageService;
    @Autowired
    private DictService dictService;

    @GetMapping()
    public ModelAndView clientUser(@RequestParam(value = "villageId",required = false) Long villageId){

        ModelAndView mav = new ModelAndView(prefix + "/info");
        if(villageId == null) {
            villageId = ShiroUtils.getSysUser().getDeptId();
        }else{
            mav = new ModelAndView(prefix + "/clientUser");
        }

        SysDept dept = deptService.selectDeptById(villageId);
        mav.addObject("dept",dept);
        mav.addObject("villageId",villageId);
        int alarmCount = clientUserService.getAlarmCount(villageId);
        int noteCount = clientUserService.getNoteCount(villageId);
        double cunTotalOrder = clientUserOrderService.countCunTotal(villageId);
        Village village = villageService.selectVillageById(villageId);
        mav.addObject("village",village);
        mav.addObject("cunTotalOrder",cunTotalOrder);
        mav.addObject("noteCount",noteCount);
        mav.addObject("alarmCount",alarmCount);
        mav.addObject("user",ShiroUtils.getSysUser());
        return mav;
    }
    @GetMapping("/info")
    public ModelAndView info(
            @RequestParam(value = "searchInput",required = false) String input,
            @RequestParam(value = "villageId",required = false) Long villageId)
    {
        ModelAndView mav = new ModelAndView(prefix + "/clientUser");
        if(villageId == null) {
            villageId = ShiroUtils.getSysUser().getDeptId();
        } else {
            SysDept dept = deptService.selectDeptById(villageId);
            mav.addObject("dept",dept);
            mav.addObject("villageId",villageId);
        }
        int alarmCount = clientUserService.getAlarmCount(villageId);
        int noteCount = clientUserService.getNoteCount(villageId);
        double cunTotalOrder = clientUserOrderService.countCunTotal(villageId);
        Village village = villageService.selectVillageById(villageId);
        mav.addObject("village",village);
        mav.addObject("cunTotalOrder",cunTotalOrder);
        mav.addObject("searchInput",input);
        mav.addObject("noteCount",noteCount);
        mav.addObject("alarmCount",alarmCount);
        mav.addObject("user",ShiroUtils.getSysUser());
        return mav;
    }


    @GetMapping("/mobile")
    public ModelAndView mobile(
            @RequestParam(value = "searchInput",required = false) String input,
            @RequestParam(value = "villageId",required = false) Long villageId)
    {
        ModelAndView mav = new ModelAndView(prefix + "/mobileList");
        mav.addObject("villageId",villageId);
        double cunTotalOrder = clientUserOrderService.countCunTotal(villageId);
        Village village = villageService.selectVillageById(villageId);
        mav.addObject("village",village);
        mav.addObject("cunTotalOrder",cunTotalOrder);
        mav.addObject("searchInput",input);
        mav.addObject("user",ShiroUtils.getSysUser());

        SysDept villageInfo = deptService.selectDeptById(villageId);
        SysDept xiangInfo = deptService.selectDeptById(villageInfo.getParentId());
        SysDept xianInfo = deptService.selectDeptById(xiangInfo.getParentId());
        mav.addObject("xiangInfo",xiangInfo);
        mav.addObject("xianInfo",xianInfo);
        mav.addObject("villageInfo",villageInfo);
        return mav;
    }

    @PostMapping("/updateResidents")
    @ResponseBody
    public AjaxResult updateResidents(@RequestBody Village village) {
        if(village.getResidents() == null){
            return AjaxResult.warn("请输入常住人口数");
        }
        SysUser user = ShiroUtils.getSysUser();
        if(village.getId() == null){
            village.setId(user.getDeptId());
        }
        village.setPopulation(villageService.countVillagePopulation(village.getId()));
        int rowCount = villageService.updateVillage(village);
        if(rowCount == 0){
            SysDept dept = deptService.selectDeptById(village.getId());
            village.setCreateBy(user.getLoginName());
            village.setName(dept.getDeptName());
            village.setCreateTime(DateUtils.getNowDate());
            villageService.insertVillage(village);
        }
        return AjaxResult.success("更新成功");
    }

    @PostMapping("/listVillage")
    @ResponseBody
    public TableDataInfo listVillage(@RequestParam(value = "villageId",required = false)Long villageId)
    {

        SysUser user = ShiroUtils.getSysUser();
        if(villageId == null){
            villageId = user.getDeptId();
        }
        startPage();
        List<VillageInfo> tableList = villageInfo(villageId,user.getDept().getParentId());
        return getDataTable(tableList);
    }

    private List<VillageInfo> villageInfo(Long villageId,Long townId){
        VillageInfo villageInfo =  villageService.selectVillageInfoByVillageId(villageId);
        List<VillageInfo> tableList = new ArrayList<>();
        if(villageInfo != null){

            Long orderConfirmed = clientUserOrderService.countOrderConnfirmed(townId);
            Long notJjm = villageInfo.getJjm() - (orderConfirmed != null?orderConfirmed:0L);
            villageInfo.setNotjjm(notJjm);
            villageInfo.setOrderAmount(clientUserOrderService.countCunTotal(villageId));
            Long baolianHuCount = clientUserService.countVillagePopulation(villageId);
            villageInfo.setBaolianhuCount(baolianHuCount == null ? 0 : baolianHuCount.intValue());
            Long baolianRenCount = baolianrenService.countByAreaId(villageId);
            villageInfo.setBaolianrenCount(baolianRenCount == null ? 0 : baolianRenCount.intValue());
            tableList.add(villageInfo);
        }
        return tableList;
    }
    /**
     * 查询村民信息列表
     */
    @PostMapping("/list")
    @ResponseBody
    public TableDataInfo list(ClientUser clientUser,
                              @RequestParam(value = "searchInput",required = false) String input,
                              @RequestParam(value = "villageId",required = false) Long villageId)
    {
        startPage();
        if(villageId == null) {
            villageId = ShiroUtils.getSysUser().getDeptId();
        }
        List<ClientUser> list = clientUserService.selectClientUserByInput(input,villageId);
        return getDataTable(list);
    }


    @PostMapping("/exportVillage")
    @ResponseBody
    public AjaxResult exportVillage(@RequestParam(value = "villageId",required = false) Long villageId) throws InvocationTargetException, IllegalAccessException {

        SysUser user = ShiroUtils.getSysUser();
        SysDept dept = user.getDept();
        if(villageId == null){
            villageId = dept.getDeptId();
        }
        dept = deptService.selectDeptById(villageId);
        List<VillageInfo> tableList = villageInfo(villageId,dept.getParentId());

        String fileName = dept.getDeptName()+"辖区内信息" + System.currentTimeMillis() + ".xlsx";

        EasyExcel.write(Global.getDownloadPath()+fileName, VillageInfo.class)
                .needHead(true)
                .head(VillageInfo.class)
                .excelType(ExcelTypeEnum.XLSX)
                .registerWriteHandler(new CustomHandler())
                .registerWriteHandler(EasyExcelUtil.getStyleStrategy()).sheet("辖区内信息").doWrite(tableList);
        return AjaxResult.success(fileName);
    }
    /**
     * 导出村民信息列表
     */
    @Log(title = "村民信息", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    @ResponseBody
    public AjaxResult export(ClientUser clientUser)
    {
        SysUser user = ShiroUtils.getSysUser();
        SysDept dept = user.getDept();
        Long villageId = 0l;
        if(clientUser == null || clientUser.getVillageId() == null){
            villageId = dept.getDeptId();
        }else{
            villageId = clientUser.getVillageId();
        }
        dept = deptService.selectDeptById(villageId);
        List<ClientUser> list = clientUserService.selectClientUserList(clientUser);
        ExcelUtil<ClientUser> util = new ExcelUtil<ClientUser>(ClientUser.class);
        return util.exportExcel(list, dept.getDeptName()+"居民信息");
    }

    public Object getCellValue(Row row, int column)
    {
        if (row == null)
        {
            return row;
        }
        Object val = "";
        try
        {
            Cell cell = row.getCell(column);
            if (com.ruoyi.common.utils.StringUtils.isNotNull(cell))
            {
                if (cell.getCellTypeEnum() == CellType.NUMERIC || cell.getCellTypeEnum() == CellType.FORMULA)
                {
                    val = cell.getNumericCellValue();
                    if (HSSFDateUtil.isCellDateFormatted(cell))
                    {
                        val = DateUtil.getJavaDate((Double) val); // POI Excel 日期格式转换
                    }
                    else
                    {
                        if ((Double) val % 1 > 0)
                        {
                            val = new DecimalFormat("0.00").format(val);
                        }
                        else
                        {
                            val = new DecimalFormat("0").format(val);
                        }
                    }
                }
                else if (cell.getCellTypeEnum() == CellType.STRING)
                {
                    val = cell.getStringCellValue();
                }
                else if (cell.getCellTypeEnum() == CellType.BOOLEAN)
                {
                    val = cell.getBooleanCellValue();
                }
                else if (cell.getCellTypeEnum() == CellType.ERROR)
                {
                    val = cell.getErrorCellValue();
                }

            }
        }
        catch (Exception e)
        {
            return val;
        }
        return val;
    }

    @PostMapping("/file/upload")
    @ResponseBody
    public AjaxResult uploadClientUser(MultipartFile file,@RequestParam(value = "villageId",required = false) Long villageId) throws Exception {
        if(villageId == null){
            villageId = ShiroUtils.getSysUser().getDeptId();
        }
        String fileName = file.getOriginalFilename();
        if(fileName.length()<6|| !fileName.substring(fileName.length()-4).equals(".xls")){
            return AjaxResult.error("文件错误，请使用xls格式的表格模版文件。");
        }
        Workbook wb = WorkbookFactory.create(file.getInputStream());
        Sheet sheet = wb.getSheetAt(0);
        if (sheet == null){
            return AjaxResult.error("文件sheet不存在");
        }
        int rows = sheet.getPhysicalNumberOfRows();
        int rowCount = 3;
        if(rows > 3) {
            List<ClientUser> records = new ArrayList<>();
            for (;rowCount < rows;rowCount ++) {
                int realRow = rowCount + 1;
                ClientUser entry = new ClientUser();
                entry.setIsIn(1);
                Row row = sheet.getRow(rowCount);
                Object idValue = getCellValue(row,0);
                if(StringUtils.isEmpty(idValue.toString())){
                    break;
                }
                Cell name = row.getCell(1);//户主姓名
                if(!StringUtils.isEmpty(name.getStringCellValue())) {
                    String cellValue = name.getStringCellValue().trim();
                    entry.setMasterName(cellValue);
                } else {
                    return AjaxResult.error("第" + realRow + "行'户主姓名'信息未正确填写。");
                }

                Object phoneNumberValue = getCellValue(row,2);
                if(phoneNumberValue != null && org.apache.commons.lang3.StringUtils.isNotBlank(phoneNumberValue.toString())) {
                    String phoneNumber = phoneNumberValue.toString().trim();
                    if(phoneNumber.length() != 11 || !StringUtils.isNumber(phoneNumber)){
                        return AjaxResult.error("第" + realRow + "行'手机号'信息未正确填写。");
                    }
                    entry.setMasterPhoneNumber(phoneNumber);
//                } else {
//                    return AjaxResult.error("第" + rowCount + "行'手机号'信息未正确填写。");
                }

                Object idCardValue = getCellValue(row,3);
//                if(idCardValue == null || !IDCardUtil.isValid(idCardValue.toString())){
                if(idCardValue == null ){
                    return AjaxResult.error("第" + realRow + "行'身份证信息'未正确填写。");
                } else {
                    entry.setMasterIdentityCardNumber(idCardValue.toString().trim());
                }
                Object keepWarmValue = getCellValue(row,4);
                if(keepWarmValue != null){
                    try {
                        int keepWarmCode = Integer.parseInt(keepWarmValue.toString().trim());
                        if(keepWarmCode < 1 || keepWarmCode > 4){
                            throw new Exception();
                        }
                        entry.setKeepwarmType(keepWarmCode);
                    } catch (Exception e) {
                        return AjaxResult.error("第" + realRow + "行'取暖方式'未正确填写。");
                    }
                } else {
                    return AjaxResult.error("第" + realRow + "行'取暖方式'未正确填写。");
                }

                Object areaValue = getCellValue(row,5);
                if(areaValue != null){
                    try {
                        int areaCode = Integer.parseInt(areaValue.toString().trim());
                        if(areaCode < 1 || areaCode > 8){
                            throw new Exception();
                        }
                        entry.setArea(areaCode);
                    } catch (Exception e) {
                        return AjaxResult.error("第" + realRow + "行'取暖面积'未正确填写。");
                    }
                } else {
                    return AjaxResult.error("第" + realRow + "行'取暖面积'未正确填写。");
                }

                Object stoveValue = getCellValue(row,6);
                if(stoveValue != null){
                    String stoveCodeValue = stoveValue.toString().trim();
                    if(stoveCodeValue.equals("是")){
                        entry.setStove(1);
                    } else if(stoveCodeValue.equals("否")){
                        entry.setStove(0);
                    } else {
                        return AjaxResult.error("第" + realRow + "行'是否配有型煤专用炉具'未正确填写。");
                    }
                } else {
                    return AjaxResult.error("第" + realRow + "行'是否配有型煤专用炉具'未正确填写。");
                }

                Object alarmValue = getCellValue(row,7);
                if(alarmValue != null){
                    String alarmCode = alarmValue.toString().trim();
                    if(alarmCode.equals("是")){
                        entry.setAlarm(1);
                    } else if(alarmCode.equals("否")){
                        entry.setAlarm(0);
                    } else {
                        return AjaxResult.error("第" + realRow + "行'是否安装一氧化碳报警'未正确填写。");
                    }
                } else {
                    return AjaxResult.error("第" + realRow + "行'是否安装一氧化碳报警'未正确填写。");
                }

                Object noteCodeValue = getCellValue(row,8);
                if(noteCodeValue != null){
                    String noteCode = noteCodeValue.toString().trim();
                    if(noteCode.equals("是")){
                        entry.setNote(1);
                    } else if(noteCode.equals("否")){
                        entry.setNote(0);
                    } else {
                        return AjaxResult.error("第" + realRow + "行'是否发放明白纸'未正确填写。");
                    }
                } else {
                    return AjaxResult.error("第" + realRow + "行'是否发放明白纸'未正确填写。");
                }

                Object mediaCodeValue = getCellValue(row,9);
                if(mediaCodeValue != null){
                    String mediaCode = mediaCodeValue.toString().trim();
                    if(mediaCode.equals("是")){
                        entry.setMedia(1);
                    } else if(mediaCode.equals("否")){
                        entry.setMedia(0);
                    } else {
                        return AjaxResult.error("第" + realRow + "行'是否进行广播媒体宣传'未正确填写。");
                    }
                } else {
                    return AjaxResult.error("第" + realRow + "行'是否进行广播媒体宣传'未正确填写。");
                }
                Object gridMemberName = getCellValue(row,10);
                if(gridMemberName != null && !StringUtils.isEmpty(gridMemberName.toString())){
                    entry.setGridName(gridMemberName.toString().trim());
                }
                Object baolianrenName = getCellValue(row,11);
                Baolianren baolianren = new Baolianren();
                if(baolianrenName != null && !StringUtils.isEmpty(baolianrenName.toString())){
                    baolianren.setName(baolianrenName.toString().trim());
                }
                Object baolianrenPhone = getCellValue(row,12);
                if(baolianrenPhone != null && !StringUtils.isEmpty(baolianrenPhone.toString())){
                    baolianren.setPhone(baolianrenPhone.toString().trim());
                }
                entry.setBaolianren(baolianren);
                entry.setCreateBy(ShiroUtils.getSysUser().getLoginName());
                entry.setVillageId(villageId);
                entry.setCreateTime(new Date());
                records.add(entry);

            }

            for(ClientUser entry : records){
                boolean isUpdate = false;
                ClientUser clientUser = clientUserService.selectByMasterNameAndIdCard(entry.getMasterName(),entry.getMasterIdentityCardNumber());
                if(clientUser != null){
                    isUpdate = true;
                    entry.setId(clientUser.getId());
                }
                saveGridMember(entry);
                saveBaolianren(entry);
                if(isUpdate){
                    clientUserService.updateClientUser(entry);
                }else{
                    clientUserService.insertClientUser(entry);
                }
            }
        } else {
            return AjaxResult.error("未在指定行读取居民信息");
        }
        return AjaxResult.success("导入成功");
    }


    /**
     * 导出二维码压缩包
     * @return
     */
    @Log(title = "村民信息", businessType = BusinessType.EXPORT)
    @GetMapping(value = "/exportQrcodeZip")
    @ResponseBody
    public AjaxResult exportQrcodeZip(HttpServletRequest request,
                                      HttpServletResponse response) {
        SysUser user = ShiroUtils.getSysUser();
        String codeBaseAddress = this.qrCodeUrl + "";
        String imageType = "jpg";// 图片类型
        String tmpFilePath = "/tmp/";
        int streamBufferSize = 1024;
        StringBuffer zipNameStringBuffer = new StringBuffer(user.getDept().getDeptName() + "二维码");

        ClientUser queryCondition = new ClientUser();
        queryCondition.setVillageId(user.getDeptId());
        //村管理员
        List<ClientUser> result = clientUserService.selectClientUserList(queryCondition);
        zipNameStringBuffer.append("压缩包");
        zipNameStringBuffer.append(result.size());
        zipNameStringBuffer.append("户");
        long begin = System.currentTimeMillis();
        //每一个村用户生成一个二维码文件
        List<File> codeFiles = Collections.synchronizedList(new ArrayList<>());
        result.parallelStream().forEach(i -> {
            String imageName = i.getMasterName() + i.getMasterPhoneNumber();
            MultiFormatWriter multiFormatWriter = new MultiFormatWriter();
            Map<EncodeHintType, String> hints = new HashMap<EncodeHintType, String>();
            hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
            try {
                BitMatrix bitMatrix = multiFormatWriter.encode(codeBaseAddress.replace("{id}",i.getId().toString()),
                        BarcodeFormat.QR_CODE, 400, 400, hints);
                int width = bitMatrix.getWidth();
                int height = bitMatrix.getHeight();
                BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
                for (int x = 0; x < width; x++) {
                    for (int y = 0; y < height; y++) {
                        image.setRGB(x, y, bitMatrix.get(x, y) ? 0xFF000000 : 0xFFFFFFFF);
                    }
                }
                int[] imageRgb = new int[width * height];
                image.getRGB(0,0,width,height,imageRgb,0,width);
                BufferedImage bg = createStringImage(i.getMasterName() + " " + i.getMasterPhoneNumber(),width,50);
                int[] imageBg = new int[width * 50];
                bg.getRGB(0,0,width,50,imageBg,0,width);

                BufferedImage destImage = new BufferedImage(width, height + 50, BufferedImage.TYPE_INT_RGB);
                destImage.setRGB(0, 0, width, height, imageRgb, 0, width); // 设置上半部分或左半部分的RGB
                destImage.setRGB(0, height, width, 50, imageBg, 0, width); // 设置
                File qrCodeImage = new File(tmpFilePath, imageName + "." + imageType);
                if (!ImageIO.write(destImage, imageType, qrCodeImage)) {
                    throw new IOException("Could not write an image of format " + imageType + " to " + qrCodeImage);
                }
                codeFiles.add(qrCodeImage);
            } catch (WriterException | IOException e) {
                e.printStackTrace();
            }
        });
        System.out.println("Create qrfile cost : "+(System.currentTimeMillis() - begin)+"");


        /**
         * 打包成zip
         */
        File zipFile = new File(tmpFilePath + "qrCodeTmp.zip");
        ZipOutputStream zos = null;
        try {
            FileOutputStream out = new FileOutputStream(zipFile);
            zos = new ZipOutputStream(out);
            for (File srcFile : codeFiles) {
                byte[] buf = new byte[streamBufferSize];
                zos.putNextEntry(new ZipEntry(srcFile.getName()));
                int len;
                FileInputStream in = new FileInputStream(srcFile);
                while ((len = in.read(buf)) != -1) {
                    zos.write(buf, 0, len);
                }
                zos.setComment("居民信息二维码压缩包");
                zos.flush();
                zos.closeEntry();
                in.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
            return AjaxResult.error("文件生成出错！");
        } finally {
            if (zos != null) {
                try {
                    zos.close();
                } catch (IOException e) {

                }
            }
        }
        try {
            response.setCharacterEncoding("utf-8");
            response.setContentType("multipart/form-data");
            response.setHeader("Content-Disposition",
                    "attachment;fileName=" +  FileUtils.setFileDownloadHeader(request,
                            zipNameStringBuffer.toString() + ".zip"));
            FileUtils.writeBytes(zipFile.getAbsolutePath(), response.getOutputStream());
        } catch (UnsupportedEncodingException e) {
            AjaxResult.error("文件下载出错！");
        } catch (IOException e) {
            AjaxResult.error("文件下载出错！");
        }
        codeFiles.forEach(i -> {
            i.delete();
        });
        return AjaxResult.success("文件下载成功");
    }

    private BufferedImage createStringImage(String content,int width,int height) {
        logger.info("qrcode image content={}",content);
        // 创建图片
        Font font = new Font("宋体",Font.BOLD, 20);
        BufferedImage image = new BufferedImage(width, height,
                BufferedImage.TYPE_INT_BGR);
        Graphics g = image.getGraphics();
        g.setClip(0, 0, width, height);
        g.setColor(Color.white);
        // 先用黑色填充整张图片,也就是背景
        g.fillRect(0, 0, width, height);
        g.setColor(Color.black);
        // 设置画笔字体
        g.setFont(font);
        /** 用于获得垂直居中y */
        Rectangle clip = g.getClipBounds();
        FontMetrics fm = g.getFontMetrics(font);
        int ascent = fm.getAscent();
        int descent = fm.getDescent();
        int stringWidth = fm.stringWidth(content);
        int y = (clip.height - (ascent + descent)) / 2 + ascent;
        g.drawString(content, width/2 - stringWidth/2, y);
        g.dispose();
        return image;
    }

    @GetMapping("/info/{clientUserId}")
    public String qrcodeInfo(@PathVariable("clientUserId") Integer clientUserId) {

        return prefix + "/clientUserInfo";
    }

    /**
     * 新增村民信息
     */
    @GetMapping("/add")
    public ModelAndView add(@RequestParam(value = "villageId",required = false) Long villageId)
    {
        ModelAndView mav = new ModelAndView(prefix + "/add");
        mav.addObject("villageId",villageId);
        return mav;
    }

    /**
     * 新增保存村民信息
     */
    @Log(title = "村民信息", businessType = BusinessType.INSERT)
    @PostMapping("/add")
    @ResponseBody
    public AjaxResult addSave(ClientUser clientUser,@RequestParam(value = "villageId",required = false) Long villageId)
    {
        SysUser user = ShiroUtils.getSysUser();
        if(villageId == null){
            villageId = user.getDeptId();
        }
        clientUser.setVillageId(villageId);
        clientUser.setCreateBy(user.getLoginName());
        clientUser.setCreateTime(new Date());
        saveGridMember(clientUser);
        saveBaolianren(clientUser);

        clientUserService.insertClientUser(clientUser);
        villageService.countVillagePopulation(villageId);
        return toAjax(1);
    }

    /**
     * 修改村民信息
     */
    @GetMapping("/edit/{id}")
    public String edit(@PathVariable("id") Long id, ModelMap mmap)
    {
        ClientUser clientUser = clientUserService.selectClientUserById(id);
        if(clientUser.getIsIn() == null){
            clientUser.setIsIn(1);
        }
        mmap.put("clientUser", clientUser);
        return prefix + "/edit";
    }


    /**
     * 修改保存村民信息
     */
    @Log(title = "村民信息", businessType = BusinessType.UPDATE)
    @PostMapping("/edit")
    @ResponseBody
    public AjaxResult editSave(ClientUser clientUser)
    {
        clientUser.setUpdateBy(ShiroUtils.getLoginName());
        clientUser.setUpdateTime(new Date());
        saveGridMember(clientUser);
        saveBaolianren(clientUser);
        return toAjax(clientUserService.updateClientUser(clientUser));
    }

    private void saveGridMember(ClientUser clientUser){
        SysUser user = ShiroUtils.getSysUser();
        if(!StringUtils.isEmpty(clientUser.getGridName())){
            GridMemeber queryCondition = new GridMemeber();
            queryCondition.setAreaId(user.getDeptId());
            queryCondition.setName(clientUser.getGridName());
            queryCondition.setCreateBy(user.getLoginName());
            queryCondition.setStatus(1);
            GridMemeber gm = gridMemeberService.insertOrUpdateGridMemeber(queryCondition,clientUser.getId());
            clientUser.setGridId(gm.getId());
        }
    }
    private void saveBaolianren(ClientUser clientUser){
        //本户不在辖区内，不保存包联人
        if(clientUser.getId() == null){
            if(clientUser.getIsIn() == null || clientUser.getIsIn() == 0){
                return;
            }
        } else{
            if(clientUser.getIsIn() == null || clientUser.getIsIn() == 0){
                clientUser.setBaolianrenId(null);
                return;
            }
        }

        SysUser user = ShiroUtils.getSysUser();
        if(clientUser.getBaolianren() == null){
            return;
        }
        if(StringUtils.isEmpty(clientUser.getBaolianren().getName())){
            clientUser.setBaolianrenId(null);
        } else {
            Baolianren baolianren = baolianrenService.selectBaolianrenByNameAndAreaId(
                    clientUser.getBaolianren().getName(),
                    clientUser.getVillageId());
            if(baolianren == null){
                baolianren = clientUser.getBaolianren();
                baolianren.setName(clientUser.getBaolianren().getName());
                baolianren.setAreaId(clientUser.getVillageId());
                baolianren.setPhone(clientUser.getBaolianren().getPhone());
                baolianren.setAreaType(4L);
                baolianren.setCreateBy(user.getLoginName());
                baolianren.setCreateTime(DateUtils.getNowDate());
                baolianrenService.insertBaolianren(baolianren);
                clientUser.setBaolianrenId(baolianren.getId());
            } else {
                baolianren.setPhone(clientUser.getBaolianren().getPhone());
                baolianrenService.updateBaolianren(baolianren);
                clientUser.setBaolianrenId(baolianren.getId());
            }
            clientUser.setBaolianrenId(baolianren.getId());
        }
    }

    /**
     * 删除村民信息
     */
    @Log(title = "村民信息", businessType = BusinessType.DELETE)
    @PostMapping( "/remove")
    @ResponseBody
    public AjaxResult remove(String ids)
    {
        return toAjax(clientUserService.deleteClientUserByIds(ids));
    }

    public AjaxResult villages() {
//        mmap.put("deptList",deptList);
        return AjaxResult.success();
    }

    @RequestMapping("/detail")
    public ModelAndView detail(@RequestParam(value = "page") String page,
                               @RequestParam(value = "villageId",required = false) Long villageId) {
        ModelAndView mav = new ModelAndView(prefix + "/detail");
        mav.addObject("page",page);
        if(villageId != null){
            mav.addObject("villageId",villageId);
        }
        return mav;
    }

    @PostMapping("/detailList")
    @ResponseBody
    public TableDataInfo detailList(@RequestParam(value = "page") String page,
                                    @RequestParam(value = "villageId",required = false) Long villageId) {
        startPage();
        SysUser user = ShiroUtils.getSysUser();
        List<ClientUser> result = new ArrayList<>();
        if(villageId == null){
            villageId = user.getDeptId();
        }
        if(page.equals("alarm")){
            result = clientUserService.selectUnistallAlarmList(villageId);
        } else if(page.equals("note")) {
            result = clientUserService.selectNoNoteList(villageId);
        }
        return getDataTable(result);
    }

    @RequestMapping("/clientUserInfo/{id}")
    public ModelAndView clientUserInfo(@PathVariable(value = "id") Long  id) {
        ModelAndView mav = new ModelAndView(prefix + "/clientUserInfo");
        ClientUser user = clientUserService.selectClientUserById(id);
        if(user.getArea() != null){
            user.setAreaValue(dictService.getLabel("keep_warn_area",user.getArea().toString()));
        }
        if(user.getKeepwarmType() != null){
            user.setKeepwarmTypeValue(dictService.getLabel("keep_warm_type",user.getKeepwarmType().toString()));
        }
        if(user.getGridId() != null){
            GridMemeber gridMemeber = gridMemeberService.selectGridMemeberById(user.getGridId());
            user.setGridMemeber(gridMemeber);
        }
        if(user.getBaolianrenId() != null){
            Baolianren baolianren = baolianrenService.selectBaolianrenById(user.getBaolianrenId());
            user.setBaolianren(baolianren);
        }
        SysDept village = deptService.selectDeptById(user.getVillageId());
        String address = deptService.mergeAddress(village);
        user.setAddress(address);
        ClientUserOrder params = new ClientUserOrder();
        params.setClientUserId(id);
        List<ClientUserOrder> orders = clientUserOrderService.selectClientUserOrderList(params);
        mav.addObject("userInfo",user);
        mav.addObject("orders",orders);
        return mav;
    }

    @RequestMapping(value = "/qrcode/{id}",produces = {MediaType.IMAGE_JPEG_VALUE})
    public void createCommonQRCode(HttpServletResponse response, @PathVariable("id") Long id) throws Exception {
        ServletOutputStream stream = null;
        String url = qrCodeUrl.replace("{id}",id.toString());
        ClientUser user = clientUserService.selectClientUserById(id);
        try {
            response.setContentType("image/jpeg");
            response.addHeader("Content-Disposition", String.format("attachment; filename=\"%s\"", URLEncoder.encode(user.getMasterName()+"_"+user.getMasterPhoneNumber()+".jpg", "utf-8")));
            stream = response.getOutputStream();
            QRCodeUtil.encode(url, stream);
        } catch (Exception e) {
            e.getStackTrace();
        } finally {
            if (stream != null) {
                stream.flush();
                stream.close();
            }
        }
    }
}
